package com.desire.test;

/**
 * @author LittleDesire
 * @description
 * @date 2022-02-19 周六 11:19
 * @since 17
 */

import java.util.ArrayList;
import java.util.List;

/**
 * 模拟 生产者消费者
 * 假设 集合内只能放一个元素, 必须生产一个(add) 消费一个(remove)   演示 wait() 和 notify()
 */
public class _60_wait_notify_生产者消费者 {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        Thread thread1 = new Thread(new Producer(list));
        Thread thread2 = new Thread(new Consumer(list));
        thread1.setName("生产者生产:");
        thread2.setName("消费者消费:");
        thread1.start();
        thread2.start();
    }
}

/**
 * 生产者线程, 负责生产, 向集合中添加一个元素
 */
class Producer implements Runnable {

    List<Object> list;

    public Producer(List<Object> list) {
        this.list = list;
    }

    @Override
    public void run() {
        // 需要一直生产
        while (true) {
            synchronized (list) {
                if (list.size() > 0) {
                    // 说明集合中有元素 (无法生产了) 所以就要消费了  该线程进入等待状态
                    try {
                        // 并且释放 当前线程占用的锁
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 能走到这一步 说明 集合中没有元素了(开始生产) 所以进行添加元素
                Object o = new Object();
                list.add(o);
                System.out.println(Thread.currentThread().getName() + "--->>" + o);
                // 将元素放进去之后  需要唤醒消费者线程来消费
                list.notifyAll();
            }
        }
    }
}

/**
 * 消费者线程, 负责消费, 在集合中移除一个元素
 */
class Consumer implements Runnable {

    List<Object> list;

    public Consumer(List<Object> list) {
        this.list = list;
    }

    @Override
    public void run() {
        // 需要一直消费
        while (true) {
            synchronized (list) {
                if (list.size() == 0) {
                    // 说明集合中有没有元素 (无法消费) 所以就要生产了  该线程进入等待状态
                    try {
                        // 并且释放 当前线程占用的锁
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 能走到这一步 说明 集合中有元素(开始消费) 所以进行移除元素
                Object o = list.remove(0);
                System.out.println(Thread.currentThread().getName() + "--->>" + o);
                // 将元素放进去之后  需要唤醒生产则会进行生产
                list.notifyAll();
            }
        }
    }
}
